def integral():
    """
    混合设计： 整体式，特征补充的混合方案

    user1, user2 分别对于商品的评分：[4, 2.2]
    alice分别于user1和user2的相关系数：[0.8, 0.7]
    alice，user1， user2的评分数量：[40, 14, 55]
    alice与user1和user2的共同评分的物品数：[6, 28]

    问题：若alice预测对物品的评分为3，试求alice对物品的偏好

    :return:
    """
    def get_init_weight(num, m=2):
        """
        获取预测用户的自权重因子
        :param m:
        :param num:
        :return:
        """
        return m * num / 50 if num < 50 else num

    def get_mix_weight(rs_num, common_num):
        """
        计算预测用户与指定用户的混合权重
        :param rs_num: 预测用户与指定用户的评分数量
        :param common_num: 预测用户与指定用户的共同评分的物品数量
        :return:
        """
        m = [num / 50 if num < 50 else 1 for num in rs_num]
        hm = 2 * m[0] * m[1] / sum(m)
        sg = common_num / 50 if common_num < 50 else 1
        return hm + sg

    # 初始化
    rho = [0.8, 0.7]
    rs = [3, 4, 2.2]
    rs_nums = [40, 14, 55]
    common_nums = [6, 28]

    # 计算
    # 自权重因子
    sw = get_init_weight(num=rs_nums[0])
    # 混合关系权重
    hw1 = get_mix_weight(rs_num=rs_nums[: -1], common_num=common_nums[0])
    hw2 = get_mix_weight(rs_num=[rs_nums[0], rs_nums[-1]], common_num=common_nums[1])
    # 预测值 = （自权重因子 * 评分 + sum(混合关系权重 * 相关系数 * 评分)） / （自权重因子 + sum(混合关系权重 * 相关系数)）
    pred = (sw * rs[0] + hw1 * rho[0] * rs[1] + hw2* rho[1] * rs[2]) / (sw + hw1 * rho[0] + hw2 * rho[1])
    print(pred)


if __name__ == '__main__':
    integral()
